<template>
  <div style="width: 100%;height:100%">
    <h1>Zego RTC Video Call</h1>
    <!-- <div class="video-wrapper">
        <h4>Remote video</h4>
        <video id="remote-video" autoplay muted playsinline controls></video>
    </div> -->
    <main v-if="!showClass">
      <section class="step0" v-if="step === 0">
        <h3>欢迎进入领格</h3>
        <div class="continer">欢迎...</div>
        <button @click="nextStep(1)">开始检测</button>
      </section>
      <section class="step1" v-if="step === 1">
        <h3>摄像头检测</h3>
        <select class="cameraList" @change="changeCamera($event)">
          <option v-for="camera in cameraList" 
                  :value="camera.deviceID"
                  >
            {{ camera.deviceName }}
          </option>
        </select>
        <div class="continer">
          <video id="local-video" autoplay muted playsinline controls></video>
        </div>
        <button @click="nextStep(2)">下一步</button>
      </section>
      <section class="step1" v-if="step === 2">
        <h3>麦克风检测</h3>
        <select class="microphoneList" @change="changeMic($event)">
          <option v-for="microphone in microphoneList" :value="microphone.deviceID">{{ microphone.deviceName }}</option>
        </select>
        <div class="continer">
          <audio id="local-audio" autoplay muted playsinline controls></audio>
          <input id="capturedSoundLevel" min="0" max="10" type="range" :value="soundLevel">
        </div>
        <button @click="nextStep(3)">下一步</button>
      </section>
      <section class="step1" v-if="step === 3">
        <h3>扬声器检测</h3>
        <div class="continer">结束</div>
        <button @click="beginClass()">进入课堂</button>
      </section>
    </main>
    <div v-if="showClass">
      <div id="local-view"></div>
    </div>
  </div>
  
</template>

<script>
import {ZegoExpressEngine} from 'zego-express-engine-webrtc'
import Vconsole from "vconsole";

export default {
  name: 'HelloWorld',
  props: {
    msg: String
  },
  data() {
    return {
      zg: null,
      appID: 1739272706,
      server: 'wss://webliveroom-test.zego.im/ws',
      userID: 'test_' + new Date().getTime(), // userID 用户自己设置，必须保证全局唯一
      userName: this.userID,// userName 用户自己设置，没有唯一性要求
      roomID: "7858", // roomID 用户自己设置，必须保证全局唯一
      effect: true,
      mixerDate: null, // 混流地址
      streamID: 'stream_' + new Date().getTime(),
      soundLevel: 3,
      showClass: sessionStorage.getItem('showClass'),// 刷新后的缓存，判断是进检查还是进课堂
      // showClass: 0,

      step: null,
      cameraList: [], 
      microphoneList: [],
      streamList: [], // 索引为0 为摄像头流&合成流；  索引为1 为纯音频流
      deviceInfo:[]  // 保存设备，刷新后直接获取创建流
    }
  },
  mounted() {
    this.init();
    new Vconsole();
  },
  methods: {
    async init() {
      this.zg = new ZegoExpressEngine(this.appID, this.server);
      this.zg.setDebugVerbose(false);
      window.zg = this.zg;
      window.streamList = this.streamList;
      window.deviceInfo = this.deviceInfo;
      zg.setSoundLevelDelegate(true, 100);
      this.zg.enableAutoSwitchDevice({microphone: true});

      this.zg.on('roomStateUpdate', async (roomID, state, errorCode, extendedData) => {
          console.warn(roomID, state, errorCode, extendedData);
          if(!errorCode) {
              if (state == 'CONNECTED') {
                this.cameraList = await this.zg.getCameras();
                this.microphoneList = await this.zg.getMicrophones();
                this.step = 0;
              }
          }
      });

      this.zg.on('audioDeviceStateChanged', async (updateType, deviceType, deviceInfo)=> {
          console.error('[audioDeviceStateChanged]', updateType, deviceType, deviceInfo);
          if(this.streamList[1]) {
              if(updateType == 'ADD') {
                  this.zg.useAudioDevice(this.streamList[0], deviceInfo.deviceId);
              }
          }
      });
      
      fetch('https://sig-liveroom-admin.zego.cloud/thirdToken/get', {
          method: "POST",
          body: JSON.stringify({
              version: '04', 
              appId: this.appID,
              idName: this.userID,
              roomId: this.roomID,
              privilege: {
                  "1": 1,
                  "2": 1
              },
              expire_time: 100000000
          }),
          dataType: "json",
          contentType: "application/json; charset=utf-8"
      }).then(rsp=> rsp.json()).then(res=> {
          console.warn('[token]', res);
          const token = res.data.token
          // 登录
          this.zg.loginRoom(this.roomID, token, { userID: this.userID, userName: this.userName }, { userUpdate: true })
              .then(rsp=> console.warn('[登录 success]', rsp)).catch(err=> console.warn('[登录 fail]', err))
      });
      // console.error('11111111', this.beginClass, !!this.beginClass)
      if(this.showClass) {
        this.deviceInfo = JSON.parse(sessionStorage.getItem('deviceInfo'));
        await this.createCameraStream();
        await this.createMicrophoneStream();
        this.beginClass();
      }
    },
    async nextStep(step) {
      this.step = step;
      switch (step) {
        case 1 :
          console.warn('[nextStep]', 1);
         this. _chacheDevice(0, this.cameraList[0].deviceID);
          await this.createCameraStream();
          document.querySelector('video').srcObject = this.streamList[0];
          break;
        case 2 :
          console.warn('[nextStep]', 2);
          this.zg.on('capturedSoundLevelUpdate', this.capturedSoundLevelUpdateCallback);
          this. _chacheDevice(1, this.microphoneList[0].deviceID);
          await this.createMicrophoneStream();
          document.querySelector('audio').srcObject = this.streamList[0];
          break;
        default : 
          this.zg.off('capturedSoundLevelUpdate', this.capturedSoundLevelUpdateCallback)
          console.warn('[nextStep] default');
      }
    },
    async createCameraStream() {
      const _tempStream = await navigator.mediaDevices.getUserMedia({video: true, audio: false})
      _tempStream && _tempStream.getTracks().forEach(track=> {
        track.stop();
      });
      let stream = await zg.createStream({camera: {audio: false, videoInput: this.deviceInfo[0]}});
      this.streamList[0];
      this.streamList[0] = stream;
      // document.querySelector('video').srcObject = stream;
    },
    async createMicrophoneStream() {
      const _tempStream = await navigator.mediaDevices.getUserMedia({video: false, audio: true})
      _tempStream && _tempStream.getTracks().forEach(track=> {
        track.stop();
      });
      let stream = await zg.createStream({camera: {video: false, audioInput: this.deviceInfo[1]}});
      this.streamList[1];
      this.streamList[1] = stream;
      let audioTrack = stream.getAudioTracks()[0];
      let isReplace = this.streamList[0].getAudioTracks()[0].enabled;// 有音轨则替换
      if(isReplace) {
        await this.zg.replaceTrack(this.streamList[0], audioTrack);
      }else {
        await this.zg.addTrack(this.streamList[0], audioTrack);
      }
      // document.querySelector('audio').srcObject = this.streamList[0];
    }, 
    capturedSoundLevelUpdateCallback(soundLevel) {
      this.soundLevel = soundLevel;
    },
    async changeCamera(e) {
      this._chacheDevice(0, this.cameraList[e.target.options.selectedIndex].deviceID);
      this.createCameraStream();
    },
    async changeMic(e) {
      this._chacheDevice(1, this.microphoneList[e.target.options.selectedIndex].deviceID);
      this.createMicrophoneStream();
    },
    _chacheDevice(type, deviceID) { // type  0 camera; 1 mic
      this.deviceInfo[type] = deviceID;
    },
    beginClass() { // 进入课堂
      this.showClass = 1;
      sessionStorage.setItem('showClass', '1');
      sessionStorage.setItem('deviceInfo', JSON.stringify(this.deviceInfo));
      setTimeout(()=> {
        const localView = this.zg.createLocalStreamView(this.streamList[0]);
        localView.play("local-view");
        this.zg.startPublishingStream(this.streamID, this.streamList[0]);
      }, 1000)
      
    }
  }
}
</script>
<style scoped>

.continer {
  width: 200px;
  height: 200px;
  background: #eee;
  margin: 10px auto;
  position: relative;
}
video, audio {
  width: 100%;
}

</style>

<!-- Add "scoped" attribute to limit CSS to this component only -->
